package com.hongyi.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.hongyi.common.framework.constant.UserConstans;
import com.hongyi.common.framework.domain.JsonResult;
import com.hongyi.common.framework.utils.string.ConvertUtils;
import com.hongyi.common.framework.utils.string.StringUtils;
import com.hongyi.common.framework.validate.EditGroup;
import com.hongyi.common.log.annotation.Log;
import com.hongyi.common.log.enums.BusinessType;
import com.hongyi.common.web.controller.BaseController;
import com.hongyi.system.domain.TreeSelect;
import com.hongyi.system.domain.dto.SysDeptDto;
import com.hongyi.system.domain.vo.SysDeptVo;
import com.hongyi.system.service.ISysDeptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 部门信息
 *
 * @author DingHao
 */
@ApiSort(value = 5)
@Api(tags = "部门信息接口")
@RestController
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController {
    /**
     * 服务对象
     */
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 获取部门列表
     *
     * @return 部门列表
     */
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "获取部门列表")
    @SaCheckPermission("system:dept:list")
    @GetMapping(value = "/list")
    public JsonResult<List<SysDeptVo>> list(SysDeptDto sysDeptDto) {
        return JsonResult.ok(sysDeptService.selectDeptList(sysDeptDto)) ;
    }

    /**
     * 查询部门列表（排除节点）
     *
     * @param deptId 部门ID
     * @return 部门列表
     */
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "查询部门列表（排除节点）")
    @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "path", dataTypeClass = Long.class, required = true)
    @SaCheckPermission("system:dept:list")
    @GetMapping(value = "/list/exclude/{deptId}")
    public JsonResult<List<SysDeptVo>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
        List<SysDeptVo> sysDeptVos = sysDeptService.selectDeptList(new SysDeptDto());
        //从sysDeptVos列表中移除满足特定条件的元素
        //移除的条件是元素中的deptId等于参数中的deptId或者元素中的ancestors包含参数中的deptId
        sysDeptVos.removeIf(sysDeptVo -> sysDeptVo.getDeptId().equals(deptId)
                || StringUtils.splitList(sysDeptVo.getAncestors()).contains(ConvertUtils.toStr(deptId)));
        return JsonResult.ok(sysDeptVos);
    }

    /**
     * 根据部门编号获取详细信息
     *
     * @param deptId 部门编号
     * @return 部门对象
     */
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "根据部门编号获取详细信息")
    @ApiImplicitParam(name = "deptId", value = "部门编号", paramType = "path", dataTypeClass = Long.class, required = true)
    @SaCheckPermission("system:dept:query")
    @GetMapping(value = "/{deptId}")
    public JsonResult<SysDeptVo> getInfo(@PathVariable Long deptId) {
        return JsonResult.ok(sysDeptService.selectDeptById(deptId));
    }

    /**
     * 获取部门下拉树列表
     *
     * @param sysDeptDto 部门对象
     * @return 部门下拉树列表
     */
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "获取部门下拉树列表")
    @GetMapping(value = "/treeselect")
    public JsonResult<List<TreeSelect>> treeSelect(SysDeptDto sysDeptDto) {
        List<SysDeptVo> deptList = sysDeptService.selectDeptList(sysDeptDto);
        return JsonResult.ok(sysDeptService.buildDeptTreeSelect(deptList));
    }

    /**
     * 加载对应角色部门列表树
     *
     * @param roleId 角色ID
     * @return 列表树
     */
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "加载对应角色部门列表树")
    @GetMapping(value = "/roleDeptTreeselect/{roleId}")
    public JsonResult<Map<String, Object>> roleDeptTreeSelect(@PathVariable("roleId") Long roleId) {
        List<SysDeptVo> depts = sysDeptService.selectDeptList(new SysDeptDto());
        Map<String, Object> map = new HashMap<>(2);
        map.put("checkedKeys", sysDeptService.selectDeptListByRoleId(roleId));
        map.put("depts", sysDeptService.buildDeptTreeSelect(depts));
        return JsonResult.ok(map);
    }

    /**
     * 新增部门
     *
     * @param sysDeptDto 部门对象
     * @return 结果
     */
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "新增部门")
    @SaCheckPermission("system:dept:add")
    @Log(title = "新增部门", businessType = BusinessType.INSERT)
    @PostMapping
    public JsonResult<Void> add(@Validated @RequestBody SysDeptDto sysDeptDto) {
        if (UserConstans.NOT_UNIQUE.equals(sysDeptService.checkDeptNameUnique(sysDeptDto))) {
            return JsonResult.fail("新增部门'" + sysDeptDto.getDeptName() + "'失败，部门名称已存在");
        }

        return toResult(sysDeptService.insertDept(sysDeptDto));
    }

    /**
     * 修改
     *
     * @param sysDeptDto 部门对象
     * @return 结果
     */
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "修改部门")
    @SaCheckPermission("system:dept:edit")
    @Log(title = "修改部门信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public JsonResult<Void> edit(@Validated(EditGroup.class) @RequestBody SysDeptDto sysDeptDto) {
        Long deptId = sysDeptDto.getDeptId();
        if (UserConstans.NOT_UNIQUE.equals(this.sysDeptService.checkDeptNameUnique(sysDeptDto))) {
            return JsonResult.fail("修改部门'" + sysDeptDto.getDeptName() + "'失败，部门名称已存在");
        } else if (sysDeptDto.getParentId().equals(sysDeptDto.getDeptId())) {
            return JsonResult.fail("修改部门'" + sysDeptDto.getDeptName() + "'失败，上级部门不能是自己");
        } else if (StringUtils.equals(UserConstans.DEPT_DISABLE, sysDeptDto.getStatus())
                && this.sysDeptService.selectNormalChildrenDeptById(sysDeptDto.getDeptId()) > 0) {
            return JsonResult.fail("该部门包含未停用的子部门！");
        }
        return toResult(sysDeptService.updateDept(sysDeptDto));
    }

    /**
     * 删除部门
     *
     * @param deptId 部门ID
     * @return 结果
     */
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "删除部门")
    @ApiImplicitParam(name = "deptId", value = "部门ID", paramType = "path", dataTypeClass = Long.class, required = true)
    @SaCheckPermission("system:dept:remove")
    @Log(title = "删除部门信息", businessType = BusinessType.DELETE)
    @DeleteMapping(value = "/{deptId}")
    public JsonResult<Void> remove(@PathVariable Long deptId) {
        if (sysDeptService.hasChildByDeptId(deptId)) {
            return JsonResult.fail("存在下级部门,不允许删除");
        }
        if (sysDeptService.checkDeptExistUser(deptId)) {
            return JsonResult.fail("部门存在用户,不允许删除");
        }
        return toResult(sysDeptService.deleteDeptById(deptId));
    }

}
